using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Globalization;

namespace Microsoft.Xna.Framework
{
	public struct Quaternion : IEquatable<Quaternion>
	{
		public float X;
		public float Y;
		public float Z;
		public float W;
		private static Quaternion _identity = new Quaternion( 0f, 0f, 0f, 1f );
		public static Quaternion Identity
		{
			get
			{
				return _identity;
			}
		}
		public Quaternion( float x, float y, float z, float w )
		{
			this.X = x;
			this.Y = y;
			this.Z = z;
			this.W = w;
		}

		public Quaternion( Vector3 vectorPart, float scalarPart )
		{
			this.X = vectorPart.X;
			this.Y = vectorPart.Y;
			this.Z = vectorPart.Z;
			this.W = scalarPart;
		}

		public override string ToString()
		{
			CultureInfo provider = CultureInfo.CurrentCulture;
			return string.Format( provider, "{{X:{0} Y:{1} Z:{2} W:{3}}}", new object[] { this.X.ToString( provider ), this.Y.ToString( provider ), this.Z.ToString( provider ), this.W.ToString( provider ) } );
		}

		public bool Equals( Quaternion other )
		{
			if ( ( ( this.X == other.X ) && ( this.Y == other.Y ) ) && ( this.Z == other.Z ) )
			{
				return ( this.W == other.W );
			}
			return false;
		}

		public override bool Equals( object obj )
		{
			bool flag = false;
			if ( obj is Quaternion )
			{
				flag = this.Equals( (Quaternion)obj );
			}
			return flag;
		}

		public override int GetHashCode()
		{
			return ( ( ( this.X.GetHashCode() + this.Y.GetHashCode() ) + this.Z.GetHashCode() ) + this.W.GetHashCode() );
		}

		public float LengthSquared()
		{
			return ( ( ( ( this.X * this.X ) + ( this.Y * this.Y ) ) + ( this.Z * this.Z ) ) + ( this.W * this.W ) );
		}

		public float Length()
		{
			float num = ( ( ( this.X * this.X ) + ( this.Y * this.Y ) ) + ( this.Z * this.Z ) ) + ( this.W * this.W );
			return (float)Math.Sqrt( (double)num );
		}

		public void Normalize()
		{
			float num2 = ( ( ( this.X * this.X ) + ( this.Y * this.Y ) ) + ( this.Z * this.Z ) ) + ( this.W * this.W );
			float num = 1f / ( (float)Math.Sqrt( (double)num2 ) );
			this.X *= num;
			this.Y *= num;
			this.Z *= num;
			this.W *= num;
		}

		public static Quaternion Normalize( Quaternion quaternion )
		{
			Quaternion quaternion2;
			float num2 = ( ( ( quaternion.X * quaternion.X ) + ( quaternion.Y * quaternion.Y ) ) + ( quaternion.Z * quaternion.Z ) ) + ( quaternion.W * quaternion.W );
			float num = 1f / ( (float)Math.Sqrt( (double)num2 ) );
			quaternion2.X = quaternion.X * num;
			quaternion2.Y = quaternion.Y * num;
			quaternion2.Z = quaternion.Z * num;
			quaternion2.W = quaternion.W * num;
			return quaternion2;
		}

		public static void Normalize( ref Quaternion quaternion, out Quaternion result )
		{
			float num2 = ( ( ( quaternion.X * quaternion.X ) + ( quaternion.Y * quaternion.Y ) ) + ( quaternion.Z * quaternion.Z ) ) + ( quaternion.W * quaternion.W );
			float num = 1f / ( (float)Math.Sqrt( (double)num2 ) );
			result.X = quaternion.X * num;
			result.Y = quaternion.Y * num;
			result.Z = quaternion.Z * num;
			result.W = quaternion.W * num;
		}

		public static Quaternion Inverse( Quaternion quaternion )
		{
			Quaternion quaternion2;
			float num2 = ( ( ( quaternion.X * quaternion.X ) + ( quaternion.Y * quaternion.Y ) ) + ( quaternion.Z * quaternion.Z ) ) + ( quaternion.W * quaternion.W );
			float num = 1f / num2;
			quaternion2.X = -quaternion.X * num;
			quaternion2.Y = -quaternion.Y * num;
			quaternion2.Z = -quaternion.Z * num;
			quaternion2.W = quaternion.W * num;
			return quaternion2;
		}

		public static void Inverse( ref Quaternion quaternion, out Quaternion result )
		{
			float num2 = ( ( ( quaternion.X * quaternion.X ) + ( quaternion.Y * quaternion.Y ) ) + ( quaternion.Z * quaternion.Z ) ) + ( quaternion.W * quaternion.W );
			float num = 1f / num2;
			result.X = -quaternion.X * num;
			result.Y = -quaternion.Y * num;
			result.Z = -quaternion.Z * num;
			result.W = quaternion.W * num;
		}

		public static Quaternion CreateFromAxisAngle( Vector3 axis, float angle )
		{
			Quaternion quaternion;
			float num2 = angle * 0.5f;
			float num = (float)Math.Sin( (double)num2 );
			float num3 = (float)Math.Cos( (double)num2 );
			quaternion.X = axis.X * num;
			quaternion.Y = axis.Y * num;
			quaternion.Z = axis.Z * num;
			quaternion.W = num3;
			return quaternion;
		}

		public static void CreateFromAxisAngle( ref Vector3 axis, float angle, out Quaternion result )
		{
			float num2 = angle * 0.5f;
			float num = (float)Math.Sin( (double)num2 );
			float num3 = (float)Math.Cos( (double)num2 );
			result.X = axis.X * num;
			result.Y = axis.Y * num;
			result.Z = axis.Z * num;
			result.W = num3;
		}

		public static Quaternion CreateFromRotationMatrix( Matrix matrix )
		{
			float num8 = ( matrix.M11 + matrix.M22 ) + matrix.M33;
			Quaternion quaternion = new Quaternion();
			if ( num8 > 0f )
			{
				float num = (float)Math.Sqrt( (double)( num8 + 1f ) );
				quaternion.W = num * 0.5f;
				num = 0.5f / num;
				quaternion.X = ( matrix.M23 - matrix.M32 ) * num;
				quaternion.Y = ( matrix.M31 - matrix.M13 ) * num;
				quaternion.Z = ( matrix.M12 - matrix.M21 ) * num;
				return quaternion;
			}
			if ( ( matrix.M11 >= matrix.M22 ) && ( matrix.M11 >= matrix.M33 ) )
			{
				float num7 = (float)Math.Sqrt( (double)( ( ( 1f + matrix.M11 ) - matrix.M22 ) - matrix.M33 ) );
				float num4 = 0.5f / num7;
				quaternion.X = 0.5f * num7;
				quaternion.Y = ( matrix.M12 + matrix.M21 ) * num4;
				quaternion.Z = ( matrix.M13 + matrix.M31 ) * num4;
				quaternion.W = ( matrix.M23 - matrix.M32 ) * num4;
				return quaternion;
			}
			if ( matrix.M22 > matrix.M33 )
			{
				float num6 = (float)Math.Sqrt( (double)( ( ( 1f + matrix.M22 ) - matrix.M11 ) - matrix.M33 ) );
				float num3 = 0.5f / num6;
				quaternion.X = ( matrix.M21 + matrix.M12 ) * num3;
				quaternion.Y = 0.5f * num6;
				quaternion.Z = ( matrix.M32 + matrix.M23 ) * num3;
				quaternion.W = ( matrix.M31 - matrix.M13 ) * num3;
				return quaternion;
			}
			float num5 = (float)Math.Sqrt( (double)( ( ( 1f + matrix.M33 ) - matrix.M11 ) - matrix.M22 ) );
			float num2 = 0.5f / num5;
			quaternion.X = ( matrix.M31 + matrix.M13 ) * num2;
			quaternion.Y = ( matrix.M32 + matrix.M23 ) * num2;
			quaternion.Z = 0.5f * num5;
			quaternion.W = ( matrix.M12 - matrix.M21 ) * num2;
			return quaternion;
		}

		public static void CreateFromRotationMatrix( ref Matrix matrix, out Quaternion result )
		{
			float num8 = ( matrix.M11 + matrix.M22 ) + matrix.M33;
			if ( num8 > 0f )
			{
				float num = (float)Math.Sqrt( (double)( num8 + 1f ) );
				result.W = num * 0.5f;
				num = 0.5f / num;
				result.X = ( matrix.M23 - matrix.M32 ) * num;
				result.Y = ( matrix.M31 - matrix.M13 ) * num;
				result.Z = ( matrix.M12 - matrix.M21 ) * num;
			}
			else if ( ( matrix.M11 >= matrix.M22 ) && ( matrix.M11 >= matrix.M33 ) )
			{
				float num7 = (float)Math.Sqrt( (double)( ( ( 1f + matrix.M11 ) - matrix.M22 ) - matrix.M33 ) );
				float num4 = 0.5f / num7;
				result.X = 0.5f * num7;
				result.Y = ( matrix.M12 + matrix.M21 ) * num4;
				result.Z = ( matrix.M13 + matrix.M31 ) * num4;
				result.W = ( matrix.M23 - matrix.M32 ) * num4;
			}
			else if ( matrix.M22 > matrix.M33 )
			{
				float num6 = (float)Math.Sqrt( (double)( ( ( 1f + matrix.M22 ) - matrix.M11 ) - matrix.M33 ) );
				float num3 = 0.5f / num6;
				result.X = ( matrix.M21 + matrix.M12 ) * num3;
				result.Y = 0.5f * num6;
				result.Z = ( matrix.M32 + matrix.M23 ) * num3;
				result.W = ( matrix.M31 - matrix.M13 ) * num3;
			}
			else
			{
				float num5 = (float)Math.Sqrt( (double)( ( ( 1f + matrix.M33 ) - matrix.M11 ) - matrix.M22 ) );
				float num2 = 0.5f / num5;
				result.X = ( matrix.M31 + matrix.M13 ) * num2;
				result.Y = ( matrix.M32 + matrix.M23 ) * num2;
				result.Z = 0.5f * num5;
				result.W = ( matrix.M12 - matrix.M21 ) * num2;
			}
		}

		public static float Dot( Quaternion quaternion1, Quaternion quaternion2 )
		{
			return ( ( ( ( quaternion1.X * quaternion2.X ) + ( quaternion1.Y * quaternion2.Y ) ) + ( quaternion1.Z * quaternion2.Z ) ) + ( quaternion1.W * quaternion2.W ) );
		}

		public static void Dot( ref Quaternion quaternion1, ref Quaternion quaternion2, out float result )
		{
			result = ( ( ( quaternion1.X * quaternion2.X ) + ( quaternion1.Y * quaternion2.Y ) ) + ( quaternion1.Z * quaternion2.Z ) ) + ( quaternion1.W * quaternion2.W );
		}

		public static Quaternion Slerp( Quaternion quaternion1, Quaternion quaternion2, float amount )
		{
			float num2;
			float num3;
			Quaternion quaternion;
			float num = amount;
			float num4 = ( ( ( quaternion1.X * quaternion2.X ) + ( quaternion1.Y * quaternion2.Y ) ) + ( quaternion1.Z * quaternion2.Z ) ) + ( quaternion1.W * quaternion2.W );
			bool flag = false;
			if ( num4 < 0f )
			{
				flag = true;
				num4 = -num4;
			}
			if ( num4 > 0.999999f )
			{
				num3 = 1f - num;
				num2 = flag ? -num : num;
			}
			else
			{
				float num5 = (float)Math.Acos( (double)num4 );
				float num6 = (float)( 1 / Math.Sin( (double)num5 ) );
				num3 = ( (float)Math.Sin( (double)( ( 1f - num ) * num5 ) ) ) * num6;
				num2 = flag ? ( ( (float)-Math.Sin( (double)( num * num5 ) ) ) * num6 ) : ( ( (float)Math.Sin( (double)( num * num5 ) ) ) * num6 );
			}
			quaternion.X = ( num3 * quaternion1.X ) + ( num2 * quaternion2.X );
			quaternion.Y = ( num3 * quaternion1.Y ) + ( num2 * quaternion2.Y );
			quaternion.Z = ( num3 * quaternion1.Z ) + ( num2 * quaternion2.Z );
			quaternion.W = ( num3 * quaternion1.W ) + ( num2 * quaternion2.W );
			return quaternion;
		}

		public static void Slerp( ref Quaternion quaternion1, ref Quaternion quaternion2, float amount, out Quaternion result )
		{
			float num2;
			float num3;
			float num = amount;
			float num4 = ( ( ( quaternion1.X * quaternion2.X ) + ( quaternion1.Y * quaternion2.Y ) ) + ( quaternion1.Z * quaternion2.Z ) ) + ( quaternion1.W * quaternion2.W );
			bool flag = false;
			if ( num4 < 0f )
			{
				flag = true;
				num4 = -num4;
			}
			if ( num4 > 0.999999f )
			{
				num3 = 1f - num;
				num2 = flag ? -num : num;
			}
			else
			{
				float num5 = (float)Math.Acos( (double)num4 );
				float num6 = (float)( 1 / Math.Sin( (double)num5 ) );
				num3 = ( (float)Math.Sin( (double)( ( 1f - num ) * num5 ) ) ) * num6;
				num2 = flag ? ( ( (float)-Math.Sin( (double)( num * num5 ) ) ) * num6 ) : ( ( (float)Math.Sin( (double)( num * num5 ) ) ) * num6 );
			}
			result.X = ( num3 * quaternion1.X ) + ( num2 * quaternion2.X );
			result.Y = ( num3 * quaternion1.Y ) + ( num2 * quaternion2.Y );
			result.Z = ( num3 * quaternion1.Z ) + ( num2 * quaternion2.Z );
			result.W = ( num3 * quaternion1.W ) + ( num2 * quaternion2.W );
		}

		public static Quaternion Lerp( Quaternion quaternion1, Quaternion quaternion2, float amount )
		{
			float num = amount;
			float num2 = 1f - num;
			Quaternion quaternion = new Quaternion();
			float num5 = ( ( ( quaternion1.X * quaternion2.X ) + ( quaternion1.Y * quaternion2.Y ) ) + ( quaternion1.Z * quaternion2.Z ) ) + ( quaternion1.W * quaternion2.W );
			if ( num5 >= 0f )
			{
				quaternion.X = ( num2 * quaternion1.X ) + ( num * quaternion2.X );
				quaternion.Y = ( num2 * quaternion1.Y ) + ( num * quaternion2.Y );
				quaternion.Z = ( num2 * quaternion1.Z ) + ( num * quaternion2.Z );
				quaternion.W = ( num2 * quaternion1.W ) + ( num * quaternion2.W );
			}
			else
			{
				quaternion.X = ( num2 * quaternion1.X ) - ( num * quaternion2.X );
				quaternion.Y = ( num2 * quaternion1.Y ) - ( num * quaternion2.Y );
				quaternion.Z = ( num2 * quaternion1.Z ) - ( num * quaternion2.Z );
				quaternion.W = ( num2 * quaternion1.W ) - ( num * quaternion2.W );
			}
			float num4 = ( ( ( quaternion.X * quaternion.X ) + ( quaternion.Y * quaternion.Y ) ) + ( quaternion.Z * quaternion.Z ) ) + ( quaternion.W * quaternion.W );
			float num3 = 1f / ( (float)Math.Sqrt( (double)num4 ) );
			quaternion.X *= num3;
			quaternion.Y *= num3;
			quaternion.Z *= num3;
			quaternion.W *= num3;
			return quaternion;
		}

		public static void Lerp( ref Quaternion quaternion1, ref Quaternion quaternion2, float amount, out Quaternion result )
		{
			float num = amount;
			float num2 = 1f - num;
			float num5 = ( ( ( quaternion1.X * quaternion2.X ) + ( quaternion1.Y * quaternion2.Y ) ) + ( quaternion1.Z * quaternion2.Z ) ) + ( quaternion1.W * quaternion2.W );
			if ( num5 >= 0f )
			{
				result.X = ( num2 * quaternion1.X ) + ( num * quaternion2.X );
				result.Y = ( num2 * quaternion1.Y ) + ( num * quaternion2.Y );
				result.Z = ( num2 * quaternion1.Z ) + ( num * quaternion2.Z );
				result.W = ( num2 * quaternion1.W ) + ( num * quaternion2.W );
			}
			else
			{
				result.X = ( num2 * quaternion1.X ) - ( num * quaternion2.X );
				result.Y = ( num2 * quaternion1.Y ) - ( num * quaternion2.Y );
				result.Z = ( num2 * quaternion1.Z ) - ( num * quaternion2.Z );
				result.W = ( num2 * quaternion1.W ) - ( num * quaternion2.W );
			}
			float num4 = ( ( ( result.X * result.X ) + ( result.Y * result.Y ) ) + ( result.Z * result.Z ) ) + ( result.W * result.W );
			float num3 = 1f / ( (float)Math.Sqrt( (double)num4 ) );
			result.X *= num3;
			result.Y *= num3;
			result.Z *= num3;
			result.W *= num3;
		}

		public static Quaternion Negate( Quaternion quaternion )
		{
			Quaternion quaternion2;
			quaternion2.X = -quaternion.X;
			quaternion2.Y = -quaternion.Y;
			quaternion2.Z = -quaternion.Z;
			quaternion2.W = -quaternion.W;
			return quaternion2;
		}

		public static void Negate( ref Quaternion quaternion, out Quaternion result )
		{
			result.X = -quaternion.X;
			result.Y = -quaternion.Y;
			result.Z = -quaternion.Z;
			result.W = -quaternion.W;
		}

		public static Quaternion Add( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			quaternion.X = quaternion1.X + quaternion2.X;
			quaternion.Y = quaternion1.Y + quaternion2.Y;
			quaternion.Z = quaternion1.Z + quaternion2.Z;
			quaternion.W = quaternion1.W + quaternion2.W;
			return quaternion;
		}

		public static void Add( ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result )
		{
			result.X = quaternion1.X + quaternion2.X;
			result.Y = quaternion1.Y + quaternion2.Y;
			result.Z = quaternion1.Z + quaternion2.Z;
			result.W = quaternion1.W + quaternion2.W;
		}

		public static Quaternion Subtract( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			quaternion.X = quaternion1.X - quaternion2.X;
			quaternion.Y = quaternion1.Y - quaternion2.Y;
			quaternion.Z = quaternion1.Z - quaternion2.Z;
			quaternion.W = quaternion1.W - quaternion2.W;
			return quaternion;
		}

		public static void Subtract( ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result )
		{
			result.X = quaternion1.X - quaternion2.X;
			result.Y = quaternion1.Y - quaternion2.Y;
			result.Z = quaternion1.Z - quaternion2.Z;
			result.W = quaternion1.W - quaternion2.W;
		}

		public static Quaternion Multiply( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			float x = quaternion1.X;
			float y = quaternion1.Y;
			float z = quaternion1.Z;
			float w = quaternion1.W;
			float num4 = quaternion2.X;
			float num3 = quaternion2.Y;
			float num2 = quaternion2.Z;
			float num = quaternion2.W;
			float num12 = ( y * num2 ) - ( z * num3 );
			float num11 = ( z * num4 ) - ( x * num2 );
			float num10 = ( x * num3 ) - ( y * num4 );
			float num9 = ( ( x * num4 ) + ( y * num3 ) ) + ( z * num2 );
			quaternion.X = ( ( x * num ) + ( num4 * w ) ) + num12;
			quaternion.Y = ( ( y * num ) + ( num3 * w ) ) + num11;
			quaternion.Z = ( ( z * num ) + ( num2 * w ) ) + num10;
			quaternion.W = ( w * num ) - num9;
			return quaternion;
		}

		public static void Multiply( ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result )
		{
			float x = quaternion1.X;
			float y = quaternion1.Y;
			float z = quaternion1.Z;
			float w = quaternion1.W;
			float num4 = quaternion2.X;
			float num3 = quaternion2.Y;
			float num2 = quaternion2.Z;
			float num = quaternion2.W;
			float num12 = ( y * num2 ) - ( z * num3 );
			float num11 = ( z * num4 ) - ( x * num2 );
			float num10 = ( x * num3 ) - ( y * num4 );
			float num9 = ( ( x * num4 ) + ( y * num3 ) ) + ( z * num2 );
			result.X = ( ( x * num ) + ( num4 * w ) ) + num12;
			result.Y = ( ( y * num ) + ( num3 * w ) ) + num11;
			result.Z = ( ( z * num ) + ( num2 * w ) ) + num10;
			result.W = ( w * num ) - num9;
		}

		public static Quaternion Multiply( Quaternion quaternion1, float scaleFactor )
		{
			Quaternion quaternion;
			quaternion.X = quaternion1.X * scaleFactor;
			quaternion.Y = quaternion1.Y * scaleFactor;
			quaternion.Z = quaternion1.Z * scaleFactor;
			quaternion.W = quaternion1.W * scaleFactor;
			return quaternion;
		}

		public static void Multiply( ref Quaternion quaternion1, float scaleFactor, out Quaternion result )
		{
			result.X = quaternion1.X * scaleFactor;
			result.Y = quaternion1.Y * scaleFactor;
			result.Z = quaternion1.Z * scaleFactor;
			result.W = quaternion1.W * scaleFactor;
		}

		public static Quaternion Divide( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			float x = quaternion1.X;
			float y = quaternion1.Y;
			float z = quaternion1.Z;
			float w = quaternion1.W;
			float num14 = ( ( ( quaternion2.X * quaternion2.X ) + ( quaternion2.Y * quaternion2.Y ) ) + ( quaternion2.Z * quaternion2.Z ) ) + ( quaternion2.W * quaternion2.W );
			float num5 = 1f / num14;
			float num4 = -quaternion2.X * num5;
			float num3 = -quaternion2.Y * num5;
			float num2 = -quaternion2.Z * num5;
			float num = quaternion2.W * num5;
			float num13 = ( y * num2 ) - ( z * num3 );
			float num12 = ( z * num4 ) - ( x * num2 );
			float num11 = ( x * num3 ) - ( y * num4 );
			float num10 = ( ( x * num4 ) + ( y * num3 ) ) + ( z * num2 );
			quaternion.X = ( ( x * num ) + ( num4 * w ) ) + num13;
			quaternion.Y = ( ( y * num ) + ( num3 * w ) ) + num12;
			quaternion.Z = ( ( z * num ) + ( num2 * w ) ) + num11;
			quaternion.W = ( w * num ) - num10;
			return quaternion;
		}

		public static void Divide( ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result )
		{
			float x = quaternion1.X;
			float y = quaternion1.Y;
			float z = quaternion1.Z;
			float w = quaternion1.W;
			float num14 = ( ( ( quaternion2.X * quaternion2.X ) + ( quaternion2.Y * quaternion2.Y ) ) + ( quaternion2.Z * quaternion2.Z ) ) + ( quaternion2.W * quaternion2.W );
			float num5 = 1f / num14;
			float num4 = -quaternion2.X * num5;
			float num3 = -quaternion2.Y * num5;
			float num2 = -quaternion2.Z * num5;
			float num = quaternion2.W * num5;
			float num13 = ( y * num2 ) - ( z * num3 );
			float num12 = ( z * num4 ) - ( x * num2 );
			float num11 = ( x * num3 ) - ( y * num4 );
			float num10 = ( ( x * num4 ) + ( y * num3 ) ) + ( z * num2 );
			result.X = ( ( x * num ) + ( num4 * w ) ) + num13;
			result.Y = ( ( y * num ) + ( num3 * w ) ) + num12;
			result.Z = ( ( z * num ) + ( num2 * w ) ) + num11;
			result.W = ( w * num ) - num10;
		}

		public static Quaternion operator -( Quaternion quaternion )
		{
			Quaternion quaternion2;
			quaternion2.X = -quaternion.X;
			quaternion2.Y = -quaternion.Y;
			quaternion2.Z = -quaternion.Z;
			quaternion2.W = -quaternion.W;
			return quaternion2;
		}

		public static bool operator ==( Quaternion quaternion1, Quaternion quaternion2 )
		{
			if ( ( ( quaternion1.X == quaternion2.X ) && ( quaternion1.Y == quaternion2.Y ) ) && ( quaternion1.Z == quaternion2.Z ) )
			{
				return ( quaternion1.W == quaternion2.W );
			}
			return false;
		}

		public static bool operator !=( Quaternion quaternion1, Quaternion quaternion2 )
		{
			if ( ( ( quaternion1.X == quaternion2.X ) && ( quaternion1.Y == quaternion2.Y ) ) && ( quaternion1.Z == quaternion2.Z ) )
			{
				return ( quaternion1.W != quaternion2.W );
			}
			return true;
		}

		public static Quaternion operator +( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			quaternion.X = quaternion1.X + quaternion2.X;
			quaternion.Y = quaternion1.Y + quaternion2.Y;
			quaternion.Z = quaternion1.Z + quaternion2.Z;
			quaternion.W = quaternion1.W + quaternion2.W;
			return quaternion;
		}

		public static Quaternion operator -( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			quaternion.X = quaternion1.X - quaternion2.X;
			quaternion.Y = quaternion1.Y - quaternion2.Y;
			quaternion.Z = quaternion1.Z - quaternion2.Z;
			quaternion.W = quaternion1.W - quaternion2.W;
			return quaternion;
		}

		public static Quaternion operator *( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			float x = quaternion1.X;
			float y = quaternion1.Y;
			float z = quaternion1.Z;
			float w = quaternion1.W;
			float num4 = quaternion2.X;
			float num3 = quaternion2.Y;
			float num2 = quaternion2.Z;
			float num = quaternion2.W;
			float num12 = ( y * num2 ) - ( z * num3 );
			float num11 = ( z * num4 ) - ( x * num2 );
			float num10 = ( x * num3 ) - ( y * num4 );
			float num9 = ( ( x * num4 ) + ( y * num3 ) ) + ( z * num2 );
			quaternion.X = ( ( x * num ) + ( num4 * w ) ) + num12;
			quaternion.Y = ( ( y * num ) + ( num3 * w ) ) + num11;
			quaternion.Z = ( ( z * num ) + ( num2 * w ) ) + num10;
			quaternion.W = ( w * num ) - num9;
			return quaternion;
		}

		public static Quaternion operator *( Quaternion quaternion1, float scaleFactor )
		{
			Quaternion quaternion;
			quaternion.X = quaternion1.X * scaleFactor;
			quaternion.Y = quaternion1.Y * scaleFactor;
			quaternion.Z = quaternion1.Z * scaleFactor;
			quaternion.W = quaternion1.W * scaleFactor;
			return quaternion;
		}

		public static Quaternion operator /( Quaternion quaternion1, Quaternion quaternion2 )
		{
			Quaternion quaternion;
			float x = quaternion1.X;
			float y = quaternion1.Y;
			float z = quaternion1.Z;
			float w = quaternion1.W;
			float num14 = ( ( ( quaternion2.X * quaternion2.X ) + ( quaternion2.Y * quaternion2.Y ) ) + ( quaternion2.Z * quaternion2.Z ) ) + ( quaternion2.W * quaternion2.W );
			float num5 = 1f / num14;
			float num4 = -quaternion2.X * num5;
			float num3 = -quaternion2.Y * num5;
			float num2 = -quaternion2.Z * num5;
			float num = quaternion2.W * num5;
			float num13 = ( y * num2 ) - ( z * num3 );
			float num12 = ( z * num4 ) - ( x * num2 );
			float num11 = ( x * num3 ) - ( y * num4 );
			float num10 = ( ( x * num4 ) + ( y * num3 ) ) + ( z * num2 );
			quaternion.X = ( ( x * num ) + ( num4 * w ) ) + num13;
			quaternion.Y = ( ( y * num ) + ( num3 * w ) ) + num12;
			quaternion.Z = ( ( z * num ) + ( num2 * w ) ) + num11;
			quaternion.W = ( w * num ) - num10;
			return quaternion;
		}

        public float Angle
        {
            get
            {
                float y = (float)Math.Sqrt( ( ( this.X * this.X ) + ( this.Y * this.Y ) ) + ( this.Z * this.Z ) );
                float x = this.W;
                if ( y > float.MaxValue )
                {
                    float num = Math.Max( Math.Abs( this.X ), Math.Max( Math.Abs( this.Y ), Math.Abs( this.Z ) ) );
                    float num5 = this.X / num;
                    float num4 = this.Y / num;
                    float num3 = this.Z / num;
                    y = (float)Math.Sqrt( ( ( num5 * num5 ) + ( num4 * num4 ) ) + ( num3 * num3 ) );
                    x = this.W / num;
                }
                return (float)( Math.Atan2( y, x ) * 114.59155902616465 );
            }
        }
    }
}